package com.liuyi.tools.kits;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author Mr.fmy
 * @version 1.0.0
 * @ClassName ArithmeticKit
 * @Description TODO 算法工具类
 * @createTime 2019/11/1 10:45
 */
public class ArithmeticKit {

    /**
     * 组合算法
     * 例如 有 M 种类型、每种类型数为 N，算出来所有组合可能性
     *
     * @param list {外层集合 M 内层集合 N} 例如 [[白色，红色],[XL,l]]
     * @return [[白色, XL], [白色, L].....]
     */
    public static <T> List<List<T>> combinational(List<List<T>> list) {
        if (CollUtil.isEmpty(list)) return new ArrayList<>();
        List<List<T>> result = new ArrayList<>();
        //只循环第一级
        list.get(0).forEach(item -> {
            if (list.size() > 1) {
                List<List<T>> recursion = combinationalRecursion(item, list, 1);
                if (recursion != null && recursion.size() > 0) {
                    result.addAll(recursion);
                }
            } else {
                result.add(Collections.singletonList(item));
            }
        });
        return result;
    }

    /**
     * 组合算法递归
     *
     * @param combinational 上一种 可能的值
     * @param list          所有可能
     * @param i             当前下标
     */
    private static <T> List<List<T>> combinationalRecursion(T combinational, List<List<T>> list, int i) {
        if (CollUtil.isEmpty(list) || ObjectUtil.isEmpty(combinational)) return null;
        if (i >= list.size()) return null;
        List<List<T>> result = new ArrayList<>();
        list.get(i).forEach(item -> {
            result.add(Arrays.asList(combinational, item));
            if (i < list.size() - 1) {
                List<List<T>> recursion = combinationalRecursion(combinational, list, i + 1);
                if (recursion != null && recursion.size() > 0) {
                    result.addAll(recursion);
                }
            }
        });
        return result;
    }
}
